package org.tloss.web.editor.projects;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.core.resources.IResourceDeltaVisitor;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.tloss.web.editor.Activator;
import org.tloss.web.editor.GeneratorHelper;
import org.tloss.web.editor.Utils;
import org.tloss.web.editor.utils.Constants;
import org.tloss.web.editor.utils.Generator;

public class WebEditorVisitor implements IResourceProxyVisitor,
		IResourceDeltaVisitor {
	IProgressMonitor monitor;

	public WebEditorVisitor(IProgressMonitor monitor) {
		this.monitor = monitor;
	}

	protected void deleteResource(String path, IProject project)
			throws CoreException {
		IFile file = project.getFile(path);
		if (file.exists()) {
			file.delete(true, monitor);
		}
	}

	public boolean visit(IResourceDelta delta) throws CoreException {

		boolean deleted = (IResourceDelta.REMOVED & delta.getKind()) != 0;
		IResource resource = delta.getResource();
		String name = resource.getName();
		if (name != null && name.endsWith(".empe")) {// entity
			if (deleted) {
				StringBuffer src = new StringBuffer();
				src.append(Utils.getProperty(resource.getProject(),
						Constants.SRC_FOLDER_PRO, Constants.SRC_FOLDER));
				src.append("/").append(Constants.ENTITY_FOLDER).append("/");
				src.append(name.replace(".empe", ".java"));
				deleteResource(src.toString(), resource.getProject());
			} else {
				processEntityResource(resource, monitor);
			}
		} else if (name != null && name.endsWith(".sqlmpe")) {// sql
			if (deleted) {
				StringBuffer src = new StringBuffer();
				src.append(Utils.getProperty(resource.getProject(),
						Constants.SRC_FOLDER_PRO, Constants.SRC_FOLDER));
				src.append("/").append(Constants.SQL_FOLDER).append("/");
				src.append(name.replace(".sqlmpe", ".java"));
				deleteResource(src.toString(), resource.getProject());
			} else {
				processSQLResource(resource, monitor);
			}
		} else if (name != null && name.endsWith(".fmpe")) {// sql
			if (deleted) {
				StringBuffer src = new StringBuffer();
				src.append(Utils.getProperty(resource.getProject(),
						Constants.SRC_FOLDER_PRO, Constants.SRC_FOLDER));
				src.append("/").append(Constants.FORMS_FOLDER).append("/");
				src.append(name.replace(".fmpe", ".java"));
				deleteResource(src.toString(), resource.getProject());
				src = new StringBuffer();
				src.append(Utils.getProperty(resource.getProject(),
						Constants.SRC_FOLDER_PRO, Constants.SRC_FOLDER));
				src.append("/").append(Constants.FORMS_FOLDER).append("/");
				src.append(name.replace(".fmpe", "Form.java"));
				deleteResource(src.toString(), resource.getProject());
			} else {
				processFormResource(resource, monitor);
			}
		}
		return true;
	}

	public boolean visit(IResourceProxy proxy) throws CoreException {
		String name = proxy.getName();
		if (name != null && name.endsWith(".empe")) {// entity
			// found a source file
			processEntityResource(proxy.requestResource(), monitor);
		} else if (name != null && name.endsWith(".sqlmpe")) {// entity
			// found a source file
			processSQLResource(proxy.requestResource(), monitor);
		} else if (name != null && name.endsWith(".fmpe")) {// entity
			// found a source file
			processFormResource(proxy.requestResource(), monitor);
		}
		return true;
	}

	private void processEntityResource(IResource resource,
			IProgressMonitor monitor) throws CoreException {
		Utils.logInfo("Processing " + resource.getFullPath());
		if (resource != null && resource instanceof IFile && resource.exists()) {
			IProject project = resource.getProject();
			Generator.generateEntity(project, new IResource[] { resource },
					monitor);
		}

	}

	private GeneratorHelper generatorHelper = new GeneratorHelper();

	private void processFormResource(IResource resource,
			IProgressMonitor monitor) throws CoreException {
		Utils.logInfo("Processing " + resource.getFullPath());
		if (resource != null && resource instanceof IFile && resource.exists()) {
			IProject project = resource.getProject();
			generatorHelper.setProject(project);
			Generator.generateForm(project, new IResource[] { resource },
					monitor, generatorHelper);
		}

	}

	private void processSQLResource(IResource resource, IProgressMonitor monitor)
			throws CoreException {
		Utils.logInfo("Processing " + resource.getFullPath());
		if (resource != null && resource instanceof IFile && resource.exists()) {
			IProject project = resource.getProject();
			generatorHelper.setProject(project);
			Generator.generateSQL(project, new IResource[] { resource },
					monitor, generatorHelper);
		}

	}

	private void processResource(IResource resource) throws CoreException {
		if (resource instanceof IFile && resource.exists()) {
			resource.deleteMarkers("org.tloss.web.editort.form.FormMarker",
					true, IResource.DEPTH_INFINITE);
			InputStream in = null;
			try {
				IFile file = (IFile) resource;
				String htmlName = file.getName().replace(".tform", ".html");
				IContainer container = file.getParent();
				IFile htmlFile = container.getFile(new Path(htmlName));
				in = file.getContents();
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				// FormTranslator.convert(new InputStreamReader(in),
				// new OutputStreamWriter(baos));
				ByteArrayInputStream contents = new ByteArrayInputStream(
						baos.toByteArray());
				if (baos.size() < 100) {
					System.out.println("Minimark file is empty");
					IMarker marker = resource
							.createMarker("org.tloss.web.editort.form.FormMarker");
					marker.setAttribute(IMarker.SEVERITY,
							IMarker.SEVERITY_ERROR);
					marker.setAttribute(IMarker.MESSAGE,
							"Minimark file is empty");
					marker.setAttribute(IMarker.LINE_NUMBER, 0);
					marker.setAttribute(IMarker.CHAR_START, 0);
					marker.setAttribute(IMarker.CHAR_END, 0);
				}
				if (htmlFile.exists()) {
					htmlFile.setContents(contents, true, false, null);
				} else {
					htmlFile.create(contents, true, null);
				}
				htmlFile.setDerived(true, null);
			} catch (Exception e) {
				throw new CoreException(new Status(Status.ERROR,
						Activator.PLUGIN_ID, "Failed to generate resource", e));
			} finally {
				try {
					in.close();
				} catch (IOException e) {
				}
			}
		}
	}

}
